{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# ABU量化系统使用文档 \n",
    "\n",
    "<center>\n",
    "        <img src=\"./image/abu_logo.png\" alt=\"\" style=\"vertical-align:middle;padding:10px 20px;\"><font size=\"6\" color=\"black\"><b>第32节 策略有效性的验证</b></font>\n",
    "</center>\n",
    "\n",
    "-----------------\n",
    "\n",
    "作者: 阿布\n",
    "\n",
    "阿布量化版权所有 未经允许 禁止转载\n",
    "\n",
    "[abu量化系统github地址](https://github.com/bbfamily/abu) (欢迎+star)\n",
    "\n",
    "[本节ipython notebook](https://github.com/bbfamily/abu/tree/master/abupy_lecture)\n",
    "\n",
    "\n",
    "上一节讲解资金仓位管理与买入策略搭配的示例，本节讲解策有效性的验证。\n",
    "\n",
    "首先导入本节需要使用的abupy中的模块： \n",
    "\n",
    "本节大多数内容无法使用沙盒数据运行，需要下载缓存，百度云地址如下：\n",
    "\n",
    "[csv格式美股，A股，港股，币类，期货6年日k数据](https://pan.baidu.com/s/1geNZgqf) 密码: gvtr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "enable example env will only read RomDataBu/csv\n"
     ]
    }
   ],
   "source": [
    "# 基础库导入\n",
    "\n",
    "from __future__ import print_function\n",
    "from __future__ import division\n",
    "\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "warnings.simplefilter('ignore')\n",
    "\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "import os\n",
    "import sys\n",
    "# 使用insert 0即只使用github，避免交叉使用了pip安装的abupy，导致的版本不一致问题\n",
    "sys.path.insert(0, os.path.abspath('../'))\n",
    "import abupy\n",
    "# 开始的示例先使用沙盒数据，之后的示例需要下载缓存\n",
    "abupy.env.enable_example_env_ipython()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "us_choice_symbols = ['usTSLA', 'usNOAH', 'usSFUN', 'usBIDU', 'usAAPL', 'usGOOG', 'usWUBA', 'usVIPS']\n",
    "cn_choice_symbols = ['002230', '300104', '300059', '601766', '600085', '600036', '600809', '000002', '002594', '002739']\n",
    "hk_choice_symbols = ['hk03333', 'hk00700', 'hk02333', 'hk01359', 'hk00656', 'hk03888', 'hk02318']\n",
    "from abupy import ABuSymbolPd, AbuUpDownTrend, AbuDownUpTrend, AbuUpDownGolden, AbuMetricsBase\n",
    "from abupy import AbuFactorCloseAtrNStop, AbuFactorAtrNStop, AbuFactorPreAtrNStop, tl, ABuProgress\n",
    "from abupy import GridSearch, AbuCrossVal, WidgetCrossVal, EMarketTargetType, abu, WidgetGridSearch"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1. UI界面: Grid Search寻找策略最优参数\n",
    "\n",
    "30，31两节都使用了abupy内置的一个长短线买入策略AbuDownUpTrend，策略默认的参数实现如下：\n",
    "1. 寻找长线下跌的股票，比如一个季度(4个月)整体趋势为下跌趋势\n",
    "2. 短线走势上涨的股票，比如一个月整体趋势为上涨趋势\n",
    "3. 最后使用海龟突破的xd日突破策略作为策略最终买入信号\n",
    "\n",
    "上面策略描述的‘一个季度(4个月)’，‘xd日突破’都是策略的默认参数，通过改变设置因子的默认参数可以修改值，而且做为判断趋势是否为上涨下跌的趋势拟合角度阀值也是可以设置的，如下将策略修改为：\n",
    "\n",
    "1. 寻找长线下跌的股票，过去120个交易日整体趋势为下跌趋势\n",
    "2. 短线走势上涨的股票，过去30个交易日整体趋势为上涨趋势\n",
    "3. 最后使用30日突破策略作为策略最终买入信号\n",
    "4. 判定趋势是否为上涨下跌的拟合角度值为+-4\n",
    "\n",
    "代码示例如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "买入后卖出的交易数量:16\n",
      "买入后尚未卖出的交易数量:0\n",
      "胜率:43.7500%\n",
      "平均获利期望:14.7855%\n",
      "平均亏损期望:-6.2479%\n",
      "盈亏比:2.1803\n",
      "所有交易收益比例和:0.4727 \n",
      "所有交易总盈亏和:249346.0300 \n"
     ]
    }
   ],
   "source": [
    "# 初始资金量\n",
    "cash = 3000000\n",
    "def run_loo_back(choice_symbols, ps=None, n_folds=3, start=None, end=None, only_info=False):\n",
    "    \"\"\"封装一个回测函数，返回回测结果，以及回测度量对象\"\"\"\n",
    "    if choice_symbols[0].startswith('us'):\n",
    "        abupy.env.g_market_target = EMarketTargetType.E_MARKET_TARGET_US\n",
    "    else:\n",
    "        abupy.env.g_market_target = EMarketTargetType.E_MARKET_TARGET_CN\n",
    "    abu_result_tuple, _ = abu.run_loop_back(cash,\n",
    "                                           buy_factors,\n",
    "                                           sell_factors,\n",
    "                                           ps,\n",
    "                                           start=start,\n",
    "                                           end=end,\n",
    "                                           n_folds=n_folds,\n",
    "                                           choice_symbols=choice_symbols)\n",
    "    ABuProgress.clear_output()\n",
    "    metrics = AbuMetricsBase.show_general(*abu_result_tuple, returns_cmp=only_info, \n",
    "                                only_info=only_info,\n",
    "                                only_show_returns=True)\n",
    "    return abu_result_tuple, metrics\n",
    "\n",
    "\"\"\"\n",
    "    买入策略使用AbuDownUpTrend:\n",
    "    短线基数xd=30: 30个交易日整体趋势为上涨趋势, 长线下跌乘数基数, 海龟突破的30日突破\n",
    "    长线乘数past_factor=4: xd * 4 = 30 * 4 = 120 过去120个交易日整体趋势为下跌趋势\n",
    "    趋势角度阀值down_deg_threshold: 判定趋势是否为上涨下跌的拟合角度值为+-4\n",
    "\"\"\"\n",
    "buy_factors = [{'class': AbuDownUpTrend, 'xd': 30, 'past_factor': 4, 'down_deg_threshold': -4}]\n",
    "sell_factors = [{'stop_loss_n': 1.0, 'stop_win_n': 3.0,\n",
    "                 'class': AbuFactorAtrNStop},\n",
    "                {'class': AbuFactorPreAtrNStop, 'pre_atr_n': 1.5},\n",
    "                {'class': AbuFactorCloseAtrNStop, 'close_atr_n': 1.5}]\n",
    "# 开始回测\n",
    "_, _ = run_loo_back(us_choice_symbols, only_info=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "从回测结果中可以看到最终收益为正值，由于使用较高的止盈位，偏倚重盈亏比值，胜率不高，最终策略是否应该使用这组参数，即最优参数的选择在‘第7节-寻找策略最优参数和评分’中讲解过，这里不过多赘述，只示例更简洁的接口使用以及ui操作。\n",
    "\n",
    "首先示例ui界面的操作使用WidgetGridSearch，如下：\n",
    "\n",
    "备注：\n",
    "\n",
    "* ui具体操作步骤在之后的视频教程中详细示例\n",
    "* 更多界面操作请直接运行abupy/abupy_ui/文件夹下的界面功能文件\n",
    "\n",
    "[更多界面操作简单示例](https://github.com/bbfamily/abu/blob/master/abupy_ui/readme.md)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "7ddeec4404744479981b8ad4e4ee46e7"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 直接启动grid search界面\n",
    "WidgetGridSearch()()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. 代码实现Grid Search寻找策略最优参数\n",
    "\n",
    "如下可以使用GridSearch.grid_search寻找买入AbuDownUpTrend策略参数：\n",
    "\n",
    "1. 短线基数'xd': [20, 30, 40]\n",
    "2. 长线乘数'past_factor': [3, 4, 5]\n",
    "3. 趋势角度阀值'down_deg_threshold':  [-2, -3, -4]\n",
    "\n",
    "寻找卖出AbuFactorAtrNStop策略参数：\n",
    "\n",
    "1. 止损atr倍数stop_loss_n：[0.5, 1.0, 1.5]\n",
    "2. 止盈atr倍数stop_win_n：[0.5, 1.0, 2.0, 3.0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "a745fe6eb65c4c56b82b4cfb834d5344"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "63c42fedf4634e99b435ba13c2ac2cb5"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "14dc2a4529c84261865b746dde79c34c"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "a18ac3659e78404aac4ac8b96060bb48"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "56934df1d836458085b825ca02687815"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "b2914465a2a2491a95735095510f7af8"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "88ea1963d80c4e3abfc14b25ea225cf0"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "16a5d37830664904aa69e94a3284a29b"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "46dcc631704b4c5db4e2f50f5ca160df"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "aa3e6614125e4962b73fb5dd84687c08"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": []
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "最佳买入因子参数组合：[{'past_factor': 5, 'class': <class 'abupy.FactorBuyBu.ABuFactorBuyTrend.AbuDownUpTrend'>, 'xd': 20, 'down_deg_threshold': -2}]\n",
      "最佳卖出因子参数组合：[{'stop_loss_n': 1.0, 'class': <class 'abupy.FactorSellBu.ABuFactorAtrNStop.AbuFactorAtrNStop'>, 'stop_win_n': 0.5}]\n",
      "****************************************************************************************************\n",
      "买入后卖出的交易数量:8\n",
      "买入后尚未卖出的交易数量:2\n",
      "胜率:100.0000%\n",
      "平均获利期望:7.4020%\n",
      "平均亏损期望:0.0000%\n",
      "盈亏比:0.0000\n",
      "所有交易收益比例和:0.5922 \n",
      "所有交易总盈亏和:830148.8000 \n"
     ]
    }
   ],
   "source": [
    "buy_factors = {'class': AbuDownUpTrend, 'xd': [20, 30, 40], \n",
    "               'past_factor': [3, 4, 5], 'down_deg_threshold': [-2, -3, -4]}\n",
    "sell_factors = [{'class': AbuFactorAtrNStop, 'stop_loss_n': [0.5, 1.0, 1.5], \n",
    "                'stop_win_n': [0.5, 1.0, 2.0, 3.0]},\n",
    "               ]\n",
    "# 使用类方法GridSearch.grid_search进行最优参数查找\n",
    "scores, score_tuple_array = GridSearch.grid_search(us_choice_symbols, buy_factors, sell_factors)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "上述最优结果输出为对所有参数评分结果的最优结果，由于策略的苛刻买入条件导致整体交易数量少，所以很多时候需要根据top n的输出结果来进行筛选使用的最优参数。\n",
    "\n",
    "使用show_top_score_metrics多显示一些最优结果，top_cnt为正数时显示评分最高的参数组合及回测结果，top_cnt为负数时相反，如下top_cnt=3显示度量结果最好的3组参数组合及回测结果："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "买入策略:[{'past_factor': 5, 'class': <class 'abupy.FactorBuyBu.ABuFactorBuyTrend.AbuDownUpTrend'>, 'xd': 20, 'down_deg_threshold': -2}]\n",
      "卖出策略:[{'stop_loss_n': 1.0, 'class': <class 'abupy.FactorSellBu.ABuFactorAtrNStop.AbuFactorAtrNStop'>, 'stop_win_n': 0.5}]\n",
      "买入后卖出的交易数量:8\n",
      "买入后尚未卖出的交易数量:2\n",
      "胜率:100.0000%\n",
      "平均获利期望:7.4020%\n",
      "平均亏损期望:0.0000%\n",
      "盈亏比:0.0000\n",
      "所有交易收益比例和:0.5922 \n",
      "所有交易总盈亏和:830148.8000 \n",
      "\n",
      "\n",
      "买入策略:[{'past_factor': 5, 'class': <class 'abupy.FactorBuyBu.ABuFactorBuyTrend.AbuDownUpTrend'>, 'xd': 20, 'down_deg_threshold': -2}]\n",
      "卖出策略:[{'stop_loss_n': 1.5, 'class': <class 'abupy.FactorSellBu.ABuFactorAtrNStop.AbuFactorAtrNStop'>, 'stop_win_n': 0.5}]\n",
      "买入后卖出的交易数量:8\n",
      "买入后尚未卖出的交易数量:2\n",
      "胜率:100.0000%\n",
      "平均获利期望:7.4020%\n",
      "平均亏损期望:0.0000%\n",
      "盈亏比:0.0000\n",
      "所有交易收益比例和:0.5922 \n",
      "所有交易总盈亏和:830148.8000 \n",
      "\n",
      "\n",
      "买入策略:[{'past_factor': 5, 'class': <class 'abupy.FactorBuyBu.ABuFactorBuyTrend.AbuDownUpTrend'>, 'xd': 20, 'down_deg_threshold': -4}]\n",
      "卖出策略:[{'stop_loss_n': 1.0, 'class': <class 'abupy.FactorSellBu.ABuFactorAtrNStop.AbuFactorAtrNStop'>, 'stop_win_n': 0.5}]\n",
      "买入后卖出的交易数量:7\n",
      "买入后尚未卖出的交易数量:1\n",
      "胜率:100.0000%\n",
      "平均获利期望:7.8207%\n",
      "平均亏损期望:0.0000%\n",
      "盈亏比:0.0000\n",
      "所有交易收益比例和:0.5475 \n",
      "所有交易总盈亏和:740741.1400 \n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "GridSearch.show_top_score_metrics(scores, score_tuple_array, top_cnt=3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如下top_cnt=-1显示度量结果最差的回测参数组合及回测结果："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "买入策略:[{'past_factor': 3, 'class': <class 'abupy.FactorBuyBu.ABuFactorBuyTrend.AbuDownUpTrend'>, 'xd': 30, 'down_deg_threshold': -4}]\n",
      "卖出策略:[{'stop_loss_n': 1.5, 'class': <class 'abupy.FactorSellBu.ABuFactorAtrNStop.AbuFactorAtrNStop'>, 'stop_win_n': 3.0}]\n",
      "买入后卖出的交易数量:6\n",
      "买入后尚未卖出的交易数量:1\n",
      "胜率:-100.0000%\n",
      "平均获利期望:0.0000%\n",
      "平均亏损期望:-19.4947%\n",
      "盈亏比:0.0000\n",
      "所有交易收益比例和:-1.1697 \n",
      "所有交易总盈亏和:-1319405.8000 \n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "GridSearch.show_top_score_metrics(scores, score_tuple_array, top_cnt=-1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3 交叉相关性策略验证\n",
    "\n",
    "通过gird search可以暂时选定策略的参数，但是进一步验证策略的**有效性**，**普适性**就需要扩大策略的回测范围以及symbol数量，可以使用全市场对策略进行多年的历史回测来验证策略的有效性，但更推荐使用abupy中内置的交叉相关性策略验证模块，它整体思路如下：\n",
    "\n",
    "1. 选择一个市场中所有的symbol，计算所有的symbol与大盘指标的相关系数值\n",
    "2. 根据计算出的相关系数值将全市场中的symbol切分成多个组\n",
    "3. 依次从各个symbol相关系数组中多次进行抽取几个symbol进行历史交易策略回测\n",
    "4. 合并计算所有相关系数组的交易回测度量结果，进行输出\n",
    "5. 合并计算每一个相关系数组中多次进行抽取的symbol的交易回测度量结果，进行输出\n",
    "\n",
    "abupy中内置的AbuCrossVal实现了上述功能，下面为使用示例：\n",
    "\n",
    "首先使用上面grid search结果的top1参数组合进行验证：\n",
    "\n",
    "* 买入策略:[{'past_factor': 3, 'xd': 30, 'down_deg_threshold': -4}]\n",
    "\n",
    "* 卖出策略:[{'stop_loss_n': 1.5, 'stop_win_n': 3.0}]\n",
    "\n",
    "代码如下所示："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "所有交叉验证交易度量结果如下：\n",
      "买入后卖出的交易总数量:1945\n",
      "胜率:63.6504%\n",
      "平均获利期望:5.4986%\n",
      "平均亏损期望:-8.9359%\n",
      "盈亏比:1.3633\n",
      "所有交易收益比例和:3.2719 \n",
      "所有交易总盈亏和:8013432.8000 \n",
      "\n",
      "\n",
      "与大盘相关度范围:(-0.983, 0.0585]验证结果如下：\n",
      "买入后卖出的交易总数量:118\n",
      "胜率:55.9322%\n",
      "平均获利期望:7.0492%\n",
      "平均亏损期望:-17.2657%\n",
      "盈亏比:1.2400\n",
      "所有交易收益比例和:-2.0740 \n",
      "所有交易总盈亏和:-1575194.6300 \n",
      "\n",
      "\n",
      "与大盘相关度范围:(0.0585, 0.123]验证结果如下：\n",
      "买入后卖出的交易总数量:163\n",
      "胜率:52.7607%\n",
      "平均获利期望:7.0947%\n",
      "平均亏损期望:-9.5202%\n",
      "盈亏比:1.0002\n",
      "所有交易收益比例和:-1.2498 \n",
      "所有交易总盈亏和:-653173.8900 \n",
      "\n",
      "\n",
      "与大盘相关度范围:(0.197, 0.266]验证结果如下：\n",
      "买入后卖出的交易总数量:180\n",
      "胜率:61.6667%\n",
      "平均获利期望:6.8414%\n",
      "平均亏损期望:-10.3985%\n",
      "盈亏比:1.2672\n",
      "所有交易收益比例和:0.2082 \n",
      "所有交易总盈亏和:549301.5200 \n",
      "\n",
      "\n",
      "与大盘相关度范围:(0.544, 0.982]验证结果如下：\n",
      "买入后卖出的交易总数量:173\n",
      "胜率:76.3006%\n",
      "平均获利期望:3.2808%\n",
      "平均亏损期望:-5.5625%\n",
      "盈亏比:2.1738\n",
      "所有交易收益比例和:2.0364 \n",
      "所有交易总盈亏和:3690507.2200 \n",
      "\n",
      "\n",
      "与大盘相关度范围:(0.123, 0.197]验证结果如下：\n",
      "买入后卖出的交易总数量:174\n",
      "胜率:54.5977%\n",
      "平均获利期望:5.5889%\n",
      "平均亏损期望:-10.6108%\n",
      "盈亏比:0.7840\n",
      "所有交易收益比例和:-2.9575 \n",
      "所有交易总盈亏和:-3593232.6200 \n",
      "\n",
      "\n",
      "与大盘相关度范围:(0.41, 0.469]验证结果如下：\n",
      "买入后卖出的交易总数量:212\n",
      "胜率:67.9245%\n",
      "平均获利期望:4.3265%\n",
      "平均亏损期望:-7.4523%\n",
      "盈亏比:1.7431\n",
      "所有交易收益比例和:1.1322 \n",
      "所有交易总盈亏和:1125995.4000 \n",
      "\n",
      "\n",
      "与大盘相关度范围:(0.469, 0.544]验证结果如下：\n",
      "买入后卖出的交易总数量:219\n",
      "胜率:67.1233%\n",
      "平均获利期望:4.2240%\n",
      "平均亏损期望:-6.0844%\n",
      "盈亏比:1.4474\n",
      "所有交易收益比例和:1.8658 \n",
      "所有交易总盈亏和:3026834.9100 \n",
      "\n",
      "\n",
      "与大盘相关度范围:(0.266, 0.314]验证结果如下：\n",
      "买入后卖出的交易总数量:224\n",
      "胜率:62.5000%\n",
      "平均获利期望:6.5416%\n",
      "平均亏损期望:-10.4021%\n",
      "盈亏比:1.1344\n",
      "所有交易收益比例和:0.3893 \n",
      "所有交易总盈亏和:538029.9900 \n",
      "\n",
      "\n",
      "与大盘相关度范围:(0.314, 0.362]验证结果如下：\n",
      "买入后卖出的交易总数量:228\n",
      "胜率:69.2982%\n",
      "平均获利期望:5.2076%\n",
      "平均亏损期望:-7.6170%\n",
      "盈亏比:1.5337\n",
      "所有交易收益比例和:2.7967 \n",
      "所有交易总盈亏和:3560297.7700 \n",
      "\n",
      "\n",
      "与大盘相关度范围:(0.362, 0.41]验证结果如下：\n",
      "买入后卖出的交易总数量:254\n",
      "胜率:62.5984%\n",
      "平均获利期望:5.6700%\n",
      "平均亏损期望:-8.3927%\n",
      "盈亏比:1.2261\n",
      "所有交易收益比例和:1.1247 \n",
      "所有交易总盈亏和:1344067.1300 \n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# 交叉相关性策略验证只支持本地非沙盒数据模式\n",
    "abupy.env.disable_example_env_ipython()\n",
    "# 使用上面grid search结果的top1参数组合进行验证\n",
    "buy_factors = [{'class': AbuDownUpTrend, 'down_deg_threshold': -2, 'past_factor': 5, 'xd': 20}]\n",
    "sell_factors = [{'stop_loss_n': 1, 'stop_win_n': 0.5,\n",
    "                 'class': AbuFactorAtrNStop},\n",
    "                {'class': AbuFactorPreAtrNStop, 'pre_atr_n': 1.5},\n",
    "                {'class': AbuFactorCloseAtrNStop, 'close_atr_n': 1.5}]\n",
    "\n",
    "cross_val = AbuCrossVal()\n",
    "cross_val.fit(buy_factors, sell_factors, cv=10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "上最终输出为\n",
    "\n",
    "* 合并计算所有相关系数组的交易回测度量结果\n",
    "* 合并计算每一个相关系数组中多次进行抽取的symbol的交易回测度量结果\n",
    "* 由于涉及随机抽取所以这里每次的运行结果都会不一样\n",
    "\n",
    "有效性判定需要根据整体策略的风格来判断：\n",
    "\n",
    "上面的激进风格的止盈止损设置，止盈位倍数(1) < 止损位倍数(0.5)，且值偏低：\n",
    "\n",
    "* 代表交易策略整体风格为均值回复类型\n",
    "* 需要交叉相关性分组结果的高胜率，盈亏比可以偏低\n",
    "* 注意很多组的平均获利期望都比平均亏损期望低。\n",
    "\n",
    "普适性的判定需要在有效性的基础上针对不同相关性组进行判定：\n",
    "\n",
    "* 上面回测结果中所有相关性回测组的胜率都大于55%, 一定程度代表普适性很好\n",
    "* 一般10组中有7组以上符合判定就可以认为策略良好。\n",
    "\n",
    "上面的运行结果由于使用随机抽取的原因每一次的运行结果都不同，所以可以多运行几次，也可以切换不同的交易市场进行验证。\n",
    "\n",
    "\n",
    "上面验证策略使用了低止盈位形成的整体策略风格为均值回复，如果要构建整体策略风格为趋势跟踪需要比较高的止盈位，但上面使用\n",
    "\n",
    "    GridSearch.show_top_score_metrics\n",
    "\n",
    "输出前top个结果都是均值回复类型的策略参数，可以使用\n",
    "    \n",
    "    GridSearch.show_top_constraints_metrics\n",
    " \n",
    "限制top的排序结果，比如下面的示例要求止盈位stop_win_n的值为3.0的情况下上面所有度量结果的排序top，代码如下所示："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "买入策略:[{'past_factor': 4, 'class': <class 'abupy.FactorBuyBu.ABuFactorBuyTrend.AbuDownUpTrend'>, 'xd': 20, 'down_deg_threshold': -4}]\n",
      "卖出策略:[{'stop_loss_n': 1.0, 'class': <class 'abupy.FactorSellBu.ABuFactorAtrNStop.AbuFactorAtrNStop'>, 'stop_win_n': 3.0}]\n",
      "买入后卖出的交易数量:3\n",
      "买入后尚未卖出的交易数量:2\n",
      "胜率:66.6667%\n",
      "平均获利期望:47.5159%\n",
      "平均亏损期望:-23.5175%\n",
      "盈亏比:5.2488\n",
      "所有交易收益比例和:0.7151 \n",
      "所有交易总盈亏和:1006187.3100 \n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "def constraints(scores, score_tuple_array, top_cnt):\n",
    "    result_top = []\n",
    "    for sc_ind in scores.index:\n",
    "        for sell_factor in score_tuple_array[sc_ind].sell_factors:\n",
    "            if 'stop_win_n' in sell_factor and sell_factor['stop_win_n'] == 3.0:\n",
    "                result_top.append(score_tuple_array[sc_ind])\n",
    "        if len(result_top) >= top_cnt:\n",
    "            return result_top\n",
    "    return result_top\n",
    "# top_cnt=1：输出stop_win_n=3.0下最好的参数组合度量结果\n",
    "GridSearch.show_top_constraints_metrics(constraints, scores, score_tuple_array, top_cnt=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "上面带参数限制条件的输出即为止盈位为3.0情况下的最好度量结果以及参数组合。\n",
    "\n",
    "下面将带参数限制条件的top1参数组合进行相关交叉验证：\n",
    "\n",
    "* 买入策略:[{'past_factor': 4, 'xd': 20, 'down_deg_threshold': -4}]\n",
    "* 卖出策略:[{'stop_loss_n': 1.0, 'stop_win_n': 3.0}]\n",
    "\n",
    "代码以及运行结果如下所示："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "所有交叉验证交易度量结果如下：\n",
      "买入后卖出的交易总数量:1328\n",
      "胜率:48.8705%\n",
      "平均获利期望:9.6774%\n",
      "平均亏损期望:-8.7472%\n",
      "盈亏比:2.1089\n",
      "所有交易收益比例和:1.0916 \n",
      "所有交易总盈亏和:8305731.2200 \n",
      "\n",
      "\n",
      "与大盘相关度范围:(-0.983, 0.0585]验证结果如下：\n",
      "买入后卖出的交易总数量:75\n",
      "胜率:37.3333%\n",
      "平均获利期望:10.0744%\n",
      "平均亏损期望:-14.9680%\n",
      "盈亏比:0.7145\n",
      "所有交易收益比例和:-4.1668 \n",
      "所有交易总盈亏和:-3601348.9600 \n",
      "\n",
      "\n",
      "与大盘相关度范围:(0.0585, 0.123]验证结果如下：\n",
      "买入后卖出的交易总数量:101\n",
      "胜率:36.6337%\n",
      "平均获利期望:9.3515%\n",
      "平均亏损期望:-10.3681%\n",
      "盈亏比:0.6095\n",
      "所有交易收益比例和:-3.4743 \n",
      "所有交易总盈亏和:-3219578.7800 \n",
      "\n",
      "\n",
      "与大盘相关度范围:(0.123, 0.197]验证结果如下：\n",
      "买入后卖出的交易总数量:108\n",
      "胜率:50.0000%\n",
      "平均获利期望:12.2473%\n",
      "平均亏损期望:-12.8210%\n",
      "盈亏比:1.2057\n",
      "所有交易收益比例和:-0.3560 \n",
      "所有交易总盈亏和:44971.2800 \n",
      "\n",
      "\n",
      "与大盘相关度范围:(0.544, 0.982]验证结果如下：\n",
      "买入后卖出的交易总数量:120\n",
      "胜率:62.5000%\n",
      "平均获利期望:6.3188%\n",
      "平均亏损期望:-4.0046%\n",
      "盈亏比:8.9209\n",
      "所有交易收益比例和:3.0121 \n",
      "所有交易总盈亏和:5099296.6300 \n",
      "\n",
      "\n",
      "与大盘相关度范围:(0.197, 0.266]验证结果如下：\n",
      "买入后卖出的交易总数量:126\n",
      "胜率:42.8571%\n",
      "平均获利期望:15.3035%\n",
      "平均亏损期望:-9.5645%\n",
      "盈亏比:2.0687\n",
      "所有交易收益比例和:3.0370 \n",
      "所有交易总盈亏和:4552595.3600 \n",
      "\n",
      "\n",
      "与大盘相关度范围:(0.41, 0.469]验证结果如下：\n",
      "买入后卖出的交易总数量:137\n",
      "胜率:51.0949%\n",
      "平均获利期望:9.0096%\n",
      "平均亏损期望:-8.3197%\n",
      "盈亏比:2.4406\n",
      "所有交易收益比例和:0.7406 \n",
      "所有交易总盈亏和:1408590.9800 \n",
      "\n",
      "\n",
      "与大盘相关度范围:(0.266, 0.314]验证结果如下：\n",
      "买入后卖出的交易总数量:164\n",
      "胜率:41.4634%\n",
      "平均获利期望:10.6555%\n",
      "平均亏损期望:-10.2247%\n",
      "盈亏比:0.8248\n",
      "所有交易收益比例和:-2.6424 \n",
      "所有交易总盈亏和:-3668550.9500 \n",
      "\n",
      "\n",
      "与大盘相关度范围:(0.469, 0.544]验证结果如下：\n",
      "买入后卖出的交易总数量:149\n",
      "胜率:55.7047%\n",
      "平均获利期望:6.7706%\n",
      "平均亏损期望:-5.3619%\n",
      "盈亏比:1.8350\n",
      "所有交易收益比例和:2.0410 \n",
      "所有交易总盈亏和:3239663.5600 \n",
      "\n",
      "\n",
      "与大盘相关度范围:(0.362, 0.41]验证结果如下：\n",
      "买入后卖出的交易总数量:170\n",
      "胜率:50.0000%\n",
      "平均获利期望:8.7658%\n",
      "平均亏损期望:-7.9418%\n",
      "盈亏比:1.3457\n",
      "所有交易收益比例和:0.6577 \n",
      "所有交易总盈亏和:1701122.0400 \n",
      "\n",
      "\n",
      "与大盘相关度范围:(0.314, 0.362]验证结果如下：\n",
      "买入后卖出的交易总数量:178\n",
      "胜率:53.3708%\n",
      "平均获利期望:9.3338%\n",
      "平均亏损期望:-7.9238%\n",
      "盈亏比:1.4177\n",
      "所有交易收益比例和:2.2426 \n",
      "所有交易总盈亏和:2748970.0600 \n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# grid search结果的带参数限制条件的top1参数\n",
    "buy_factors = [{'class': AbuDownUpTrend, 'down_deg_threshold': -3, 'past_factor': 4, 'xd': 20}]\n",
    "# 限制条件为stop_win_n值为3.0\n",
    "sell_factors = [{'stop_loss_n': 1.5, 'stop_win_n': 3.0,\n",
    "                 'class': AbuFactorAtrNStop},\n",
    "                {'class': AbuFactorPreAtrNStop, 'pre_atr_n': 1.5},\n",
    "                {'class': AbuFactorCloseAtrNStop, 'close_atr_n': 1.5}]\n",
    "cross_val.fit(buy_factors, sell_factors, cv=10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "上面的整体风格的止盈止损设置，止盈位倍数(3.0) >> 止损位倍数(1.0)，止盈位偏高：\n",
    "\n",
    "* 代表交易策略整体风格为趋势跟踪类型\n",
    "* 总体交叉验证交易度量胜率低于50%符合趋势跟踪风格，\n",
    "* 所有平均获利期望 > 平均亏损期望低。\n",
    "* 有一组相关回测组的胜率以及盈亏比都偏低导致收益总盈亏为负值\n",
    "\n",
    "为保证策略的有效，可以多次运行进行验证。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "fit运行后所有的交易回测结果都可以使用show_cross_val_se进行查看，通过start，end参数设置游标，如下示例："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "回测symbol:['usPVTD' 'usNQP' 'usLXP-C' 'usHTF' 'usEVHC' 'usEGT' 'usCIZN' 'usDGICB'\n",
      " 'usMPB' 'usDTUL']\n",
      "回测symbol与大盘相关度范围:(-0.983, 0.0585]\n",
      "买入后卖出的交易数量:5\n",
      "买入后尚未卖出的交易数量:0\n",
      "胜率:40.0000%\n",
      "平均获利期望:7.0152%\n",
      "平均亏损期望:-8.2043%\n",
      "盈亏比:1.0766\n",
      "所有交易收益比例和:-0.0238 \n",
      "所有交易总盈亏和:15266.0900 \n",
      "\n",
      "\n",
      "回测symbol:['usAMRS' 'usHBANP' 'usSIEB' 'usNXJ' 'usKTN' 'usSD' 'usTDI' 'usTCI'\n",
      " 'usXPLR' 'usNYMX']\n",
      "回测symbol与大盘相关度范围:(-0.983, 0.0585]\n",
      "买入后卖出的交易数量:15\n",
      "买入后尚未卖出的交易数量:0\n",
      "胜率:26.6667%\n",
      "平均获利期望:15.7032%\n",
      "平均亏损期望:-19.8829%\n",
      "盈亏比:0.4019\n",
      "所有交易收益比例和:-1.5590 \n",
      "所有交易总盈亏和:-1278037.9400 \n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "cross_val.show_cross_val_se(start=8, end=10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4. 人工分析比人工智能要聪明, 懂事\n",
    "\n",
    "除了上述最终度量结果做为策略最终有效性，普适性的判别标准外，还可以把上面相关交叉验证回测的所有交易都通过可视化接口保存在本地，然后一个一个的查看交易的买入点与卖出点，排查策略是否存在问题，以及是否存在改进方案等。\n",
    "\n",
    "可以使用plot_all_cross_val_orders接口对交叉验证回测的所有交易进行保存，保存结果如下所示：\n",
    "\n",
    "![](./image/save_cv.png)\n",
    "\n",
    "\n",
    "备注：再次强调：对交易策略结果的人工分析，注重分析失败的结果以及是否存在改进方案，改进方案是否会引进新的问题是非常重要的，不要排斥人工, 人工分析比人工智能要聪明, 懂事。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "cross_val.plot_all_cross_val_orders()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "保存完成后，快照将保存在~/abu/data/save_png下当前日期的文件夹中，可使用如下命令直接打开查看："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "if abupy.env.g_is_mac_os:\n",
    "    !open $abupy.env.g_project_data_dir\n",
    "else:\n",
    "    !echo $abupy.env.g_project_data_dir"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 5. UI界面: 交叉相关性策略验证\n",
    "\n",
    "与寻找最优参数类似，可以使用WidgetCrossVal进行界面操作进行交叉相关性策略验证，如下：\n",
    "\n",
    "备注：\n",
    "\n",
    "* ui具体操作步骤在之后的视频教程中详细示例\n",
    "* 更多界面操作请直接运行abupy/abupy_ui/文件夹下的界面功能文件\n",
    "\n",
    "[更多界面操作简单示例](https://github.com/bbfamily/abu/blob/master/abupy_ui/readme.md)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "21450d84428444038f8d3cf2ed7dccd0"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "WidgetCrossVal()()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### abu量化文档目录章节\n",
    "\n",
    "1. [择时策略的开发](http://www.abuquant.com/lecture/lecture_1.html)\n",
    "2. [择时策略的优化](http://www.abuquant.com/lecture/lecture_2.html)\n",
    "3. [滑点策略与交易手续费](http://www.abuquant.com/lecture/lecture_3.html)\n",
    "4. [多支股票择时回测与仓位管理](http://www.abuquant.com/lecture/lecture_4.html)\n",
    "5. [选股策略的开发](http://www.abuquant.com/lecture/lecture_5.html)\n",
    "6. [回测结果的度量](http://www.abuquant.com/lecture/lecture_6.html)\n",
    "7. [寻找策略最优参数和评分](http://www.abuquant.com/lecture/lecture_7.html)\n",
    "8. [A股市场的回测](http://www.abuquant.com/lecture/lecture_8.html)\n",
    "9. [港股市场的回测](http://www.abuquant.com/lecture/lecture_9.html)\n",
    "10. [比特币，莱特币的回测](http://www.abuquant.com/lecture/lecture_10.html)\n",
    "11. [期货市场的回测](http://www.abuquant.com/lecture/lecture_11.html)\n",
    "12. [机器学习与比特币示例](http://www.abuquant.com/lecture/lecture_12.html)\n",
    "13. [量化技术分析应用](http://www.abuquant.com/lecture/lecture_13.html)\n",
    "14. [量化相关性分析应用](http://www.abuquant.com/lecture/lecture_14.html)\n",
    "15. [量化交易和搜索引擎](http://www.abuquant.com/lecture/lecture_15.html)\n",
    "16. [UMP主裁交易决策](http://www.abuquant.com/lecture/lecture_16.html)\n",
    "17. [UMP边裁交易决策](http://www.abuquant.com/lecture/lecture_17.html)\n",
    "18. [自定义裁判决策交易](http://www.abuquant.com/lecture/lecture_18.html)\n",
    "19. [数据源](http://www.abuquant.com/lecture/lecture_19.html)\n",
    "20. [A股全市场回测](http://www.abuquant.com/lecture/lecture_20.html)\n",
    "21. [A股UMP决策](http://www.abuquant.com/lecture/lecture_21.html)\n",
    "22. [美股全市场回测](http://www.abuquant.com/lecture/lecture_22.html)\n",
    "23. [美股UMP决策](http://www.abuquant.com/lecture/lecture_23.html)\n",
    "\n",
    "abu量化系统文档教程持续更新中，请关注公众号中的更新提醒。\n",
    "\n",
    "#### 《量化交易之路》目录章节及随书代码地址\n",
    "\n",
    "1. [第二章 量化语言——Python](https://github.com/bbfamily/abu/tree/master/ipython/第二章-量化语言——Python.ipynb)\n",
    "2. [第三章 量化工具——NumPy](https://github.com/bbfamily/abu/tree/master/ipython/第三章-量化工具——NumPy.ipynb)\n",
    "3. [第四章 量化工具——pandas](https://github.com/bbfamily/abu/tree/master/ipython/第四章-量化工具——pandas.ipynb)\n",
    "4. [第五章 量化工具——可视化](https://github.com/bbfamily/abu/tree/master/ipython/第五章-量化工具——可视化.ipynb)\n",
    "5. [第六章 量化工具——数学：你一生的追求到底能带来多少幸福](https://github.com/bbfamily/abu/tree/master/ipython/第六章-量化工具——数学.ipynb)\n",
    "6. [第七章 量化系统——入门：三只小猪股票投资的故事](https://github.com/bbfamily/abu/tree/master/ipython/第七章-量化系统——入门.ipynb)\n",
    "7. [第八章 量化系统——开发](https://github.com/bbfamily/abu/tree/master/ipython/第八章-量化系统——开发.ipynb)\n",
    "8. [第九章 量化系统——度量与优化](https://github.com/bbfamily/abu/tree/master/ipython/第九章-量化系统——度量与优化.ipynb)\n",
    "9. [第十章 量化系统——机器学习•猪老三](https://github.com/bbfamily/abu/tree/master/ipython/第十章-量化系统——机器学习•猪老三.ipynb)\n",
    "10. [第十一章 量化系统——机器学习•ABU](https://github.com/bbfamily/abu/tree/master/ipython/第十一章-量化系统——机器学习•ABU.ipynb)\n",
    "11. [附录A 量化环境部署](https://github.com/bbfamily/abu/tree/master/ipython/附录A-量化环境部署.ipynb)\n",
    "12. [附录B 量化相关性分析](https://github.com/bbfamily/abu/tree/master/ipython/附录B-量化相关性分析.ipynb)\n",
    "13. [附录C 量化统计分析及指标应用](https://github.com/bbfamily/abu/tree/master/ipython/附录C-量化统计分析及指标应用.ipynb)\n",
    "\n",
    "[更多阿布量化量化技术文章](http://www.abuquant.com/article)\n",
    "\n",
    "\n",
    "更多关于量化交易相关请阅读[《量化交易之路》](http://www.abuquant.com/books/quantify-trading-road.html)\n",
    "\n",
    "更多关于量化交易与机器学习相关请阅读[《机器学习之路》](http://www.abuquant.com/books/machine-learning-road.html)\n",
    "\n",
    "更多关于abu量化系统请关注微信公众号: abu_quant\n",
    "\n",
    "![](./image/qrcode.jpg)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.2"
  },
  "widgets": {
   "state": {
    "c0b89918956049b1bf85daea466051be": {
     "views": [
      {
       "cell_index": 5
      }
     ]
    }
   },
   "version": "1.2.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
